package com.srv.common;

import java.util.HashMap;
import java.util.Iterator;
import java.util.Map;

import com.srv.persistence.PersistenceException;
import com.srv.util.ConfigProps;
import com.srv.util.StringUtil;



public class DataSourceProps {
	private static Map<String, DataSourceProps> dataSourceMap = new HashMap<String, DataSourceProps>();

	public static String PREFIX_KEY_DATASOURCE = "datasource.";
    //the keys of the configure attributes
    public static String SUB_KEY_DATABASE_TYPE = ".databaseType";
    public static String SUB_KEY_CONN_POOL_TYPE = ".connPoolType";

    public static String SUB_KEY_USER_NAME = ".userName";
    public static String SUB_KEY_PASSWORD = ".password";
    public static String SUB_KEY_PASSWORD_DESKEY = ".password.deskey";

    public static String SUB_KEY_DRIVER_CLASS_NAME = ".driverClassName";
    public static String SUB_KEY_URL = ".url";
    public static String SUB_KEY_VALIDATE_SQL = ".validatesql";

    public static String SUB_KEY_MAX_ACTIVE = ".maxActive";
    public static String SUB_KEY_MAX_IDLE = ".maxIdle";
    public static String SUB_KEY_MAX_INITIAL_SIZE = ".initialSize";
    public static String SUB_KEY_MAX_WAIT = ".maxWait";
    public static String SUB_KEY_MAX_STATEMENTS = ".maxStatements";

    //the datasource props members
    private String dataSourceName;
    private String dataSourceURL;

    //The fully qualified Java class name of the JDBC driver to be used.
    private String dataSourceDriverClassName;
    private String dataSourceUserName;
    private String dataSourcePassword;
//    private String dataSourcePasswordDesKey;

    //
    private String dataSourceValidateSQL;

    //The initial number of connections that are created when the pool is started.
    private int dataSourceInitialSize = 3;
    //The maximum number of active connections that
    //can be allocated from this pool at the same time, or non-positive for no limit.
    private int dataSourceMaxActive = 15;
    //The maximum number of milliseconds that the pool will wait (when there are no available connections)
    //for a connection to be returned before throwing an exception, or -1 to wait indefinitely.
    private long dataSourceMaxWait = 10000;     //checkoutTimeout
    //The maximum number of connections that can remain idle in the pool,
    //without extra ones being released, or negative for no limit.
    private int dataSourceMaxIdle = 5;
    //The maximum number of open statements that can be allocated from the statement pool
    //at the same time, or non-positive for no limit.
    private int dataSourceMaxStatements = 0;

    /**
     * constuctor by the props and name
     *
     * @param extPros
     * @param dsName
     * @throws DataSourceException
     */
    public DataSourceProps(String dsName) throws PersistenceException{
    	ConfigProps config = ConfigProps.get();
    	
        dataSourceName = dsName;

        dataSourceURL = config.getString(PREFIX_KEY_DATASOURCE + dataSourceName + SUB_KEY_URL);
        dataSourceDriverClassName = config.getString(PREFIX_KEY_DATASOURCE + dataSourceName + SUB_KEY_DRIVER_CLASS_NAME);
        dataSourceUserName = config.getString(PREFIX_KEY_DATASOURCE + dataSourceName + SUB_KEY_USER_NAME);
        dataSourcePassword = config.getString(PREFIX_KEY_DATASOURCE + dataSourceName + SUB_KEY_PASSWORD);
//        dataSourcePasswordDesKey = config.getString(PREFIX_KEY_DATASOURCE + dataSourceName + SUB_KEY_PASSWORD_DESKEY);
        dataSourceValidateSQL = config.getString(PREFIX_KEY_DATASOURCE + dataSourceName + SUB_KEY_VALIDATE_SQL);


        //the pool parameter
        dataSourceInitialSize = config.getInt(PREFIX_KEY_DATASOURCE + dataSourceName + SUB_KEY_MAX_INITIAL_SIZE, dataSourceInitialSize);
        dataSourceMaxActive = config.getInt(PREFIX_KEY_DATASOURCE + dataSourceName + SUB_KEY_MAX_ACTIVE, dataSourceMaxActive);
        dataSourceMaxWait = config.getLong(PREFIX_KEY_DATASOURCE + dataSourceName + SUB_KEY_MAX_WAIT, dataSourceMaxWait);
        dataSourceMaxIdle = config.getInt(PREFIX_KEY_DATASOURCE + dataSourceName + SUB_KEY_MAX_IDLE, dataSourceMaxIdle);
        dataSourceMaxStatements = config.getInt(PREFIX_KEY_DATASOURCE + dataSourceName + SUB_KEY_MAX_IDLE, dataSourceMaxStatements);

        if (StringUtil.isEmpty(dataSourceURL) ||
                StringUtil.isEmpty(dataSourceDriverClassName) ||
                StringUtil.isEmpty(dataSourceUserName) ||
                StringUtil.isEmpty(dataSourcePassword)) {
            throw new PersistenceException("The configure of datasource missed some values.");
        }

        dataSourceMap.put(dataSourceName, this);
    }


    public String getName() {
        return dataSourceName;
    }

    public String getUrl() {
        return dataSourceURL;
    }

    public String getDriverClassName() {
        return dataSourceDriverClassName;
    }

    public String getUserName() {
        return dataSourceUserName;
    }

    public String getPassword() {
        return dataSourcePassword;
    }

//    public String getPasswordDesKey() {
//        return dataSourcePasswordDesKey;
//    }

    public String getValidateSQL() {
        return dataSourceValidateSQL;
    }

    public int getMaxActive() {
        return dataSourceMaxActive;
    }

    public int getInitialSize() {
        return dataSourceInitialSize;
    }

    public long getMaxWait() {
        return dataSourceMaxWait;
    }

    public int getMaxIdle() {
        return dataSourceMaxIdle;
    }

    public int getMaxStatements() {
        return dataSourceMaxStatements;
    }

    public String toString() {
        return "DataSourceProps {" + "Name:" + dataSourceName +
                "; DriverClassName: " + dataSourceDriverClassName +
                "; URL:" + dataSourceURL +
                "; UserName:" + dataSourceUserName +
                "; Password:" + dataSourcePassword +
                "; InitialSize:" + dataSourceInitialSize +
                "; MaxActive:" + dataSourceMaxActive +
                "; MaxIdle:" + dataSourceMaxIdle +
                "; MaxWait:" + dataSourceMaxWait +
                "; MaxStatements:" + dataSourceMaxStatements +
                "}";
    }

    public static Iterator getDataSourcePropsItr() {
        return dataSourceMap.values().iterator();
    }

    public static DataSourceProps getDataSourceProps(String dsName) {
        return dataSourceMap.get(dsName.toLowerCase());
    }

    public static boolean hasDataSourceProps(String name) {
        return dataSourceMap.containsKey(name.toLowerCase());
    }
}
